#include "Widget.h"

Widget::Widget(QWidget *parent) :
    QWidget(parent)
{
    setupUi(this);

    this->setWindowFlags(Qt::CustomizeWindowHint);
    this->showMaximized();
    frmTotal->move(QApplication::desktop()->availableGeometry().center() - this->rect().center());
    ///
    soundProcess    = new QProcess(this);
    connect(soundProcess, SIGNAL(finished(int)), this, SLOT(soundPlayEnd(int)));
    ///
    printer         = new PrinterPdf(this);
    connect(this, SIGNAL(printFile()), printer, SLOT(printing()));
    connect(printer, SIGNAL(printed()), this, SLOT(finishedPrint()));
    ///
    ftp             = new FtpClient();
    connect(this, SIGNAL(uploadFile()), ftp, SLOT(startUpload()));
    connect(ftp, SIGNAL(finishedUpload(bool)), this, SLOT(finishFileUpload(bool)));
    ///
    smtp            = new Smtp("ronimarch@gmail.com", "rnldmrtnz", "smtp.gmail.com", 465);
    connect(smtp, SIGNAL(status(QString)), this, SLOT(mailSent(QString)));
    ///
    timer           = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(timerHit()));
    connect(timer, SIGNAL(timeout()), this, SLOT(showDigitalWatch()));
    ///
//    freeTableDlg    = new FreeTableDlg();
//    connect(timer, SIGNAL(timeout()), &freeTableDlg, SLOT(showLcdDisplay()));
    ///
    /// \brief initialize
    ///
    initialize();
    /// lauch login dialog
//    QTimer::singleShot(0, this, SLOT(openDialog()));
    // file to set app's parameters
//    qDebug() << param.fileName();
    qDebug() << "end of Widget()";
}

Widget::~Widget()
{
    db.close();
}

void Widget::initialize()
{
    startTimer();
    // timer start at zero seg and has as limit 59 seg
    upperLimit  = 59;
    /// boolean value at timer that trigger checkEnabledTablelist
    bCheck  = false;
    /// timer's counter
    counter = QTime::currentTime().second();
    // setting query
    visibleRows = 8;
    /// Total tables
    nTables = 23;
    /// visible digits, digital watch, show at start of appm then it is changing by timerHit()
    showDigitalWatch();
    ///
    /*
      table_rentals;
    +-----------------+----------+---------------------+---------+-------+
    | table_rental_id | table_id | init_time           | minutes | money |
    +-----------------+----------+---------------------+---------+-------+
      tables;
    +----------+-------------+------+
    | table_id | description | type |
    +----------+-------------+------+
    */

    fld_tri = "table_rental_id";
    fld_tid = "table_id";
    fld_i_t = "init_time";
    fld_min = "minutes";
    fld_mon = "money";
    fld_dsc = "description";
    fld_typ = "type";

    if ( connection() )
    {
        // database
        QSqlQuery query;
        query.exec("set time_zone = '-5:00'");

        /// after connection() is established and getStatusTables() is executed
//        getStatusTables();

        // fill tables list
        queryFillTableLists();

        // all records of table
        qDebug() << "getTypeOfTable :" << getTypeOfTable(2);
    }

    setModels();
    // fill all lists tables, tell to app which one tab is selected '0' and update lists of tables
    on_tabWidget_currentChanged();

    /// time intervals
    intervals << "5" << "10" << "15" << "20" << "25" << "30" << "35" << "40" << "45" << "50" << "55" << "60" << "LIBRE";
    bIsEnabledTableSelected = true;                     // list of enabled tables by default
    updateIntervalCbx();

    // what time is executed this process?
//    homework();
    /*
    qDebug() << verifyUser("zeus", "zeus");
    qDebug() << verifyUser("atenea", "poseidon");
    qDebug() << verifyUser("poseidon", "poseidon");
    qDebug() << verifyUser("atenea", "zeus");
    qDebug() << verifyUser("atenea", "atenea");
    qDebug() << verifyUser("dios", "poseidon");
    */
}

bool Widget::connection(int host)
{
    if (host != 0 && host != 1) return false;

    QString qDatabase           = "QMYSQL";

    QString qHostName           = param.value("Conectividad/IP").toString();//"localhost";
    if (host == 1)  qHostName   = "188.138.24.214";
    qDebug() << "HostName =" << qHostName;
    QString qDatabaseName       = "industr1_Prueba";
    QString qUserName           = "industr1_usuario";
    QString qPassword           = "dwnpdll";
    int     iPort               = 3306;

    db = QSqlDatabase::addDatabase(qDatabase);
    db.setHostName(qHostName);
    db.setDatabaseName(qDatabaseName);
    db.setUserName(qUserName);
    db.setPassword(qPassword);
    db.setPort(iPort);

    bool    conn    = false;
    // number of seconds to wait for connection?
    (db.open()) ? (conn = true) : (conn = false);
    qDebug() << "lastError() :" << db.lastError().text();
    if ( !conn )    qDebug() << "No connection, it is not possible make queries";
    return conn;
}

void Widget::setModels()
{
    for (int i = 0; i < nTables; i++)   // all of tables in nTables initialize()
    {
//        qDebug() << "i :" << i;
        Modelo[i] = new MySqlQueryModel;
        Modelo[i]->setQuery(queryRentalsByTable(i+1));  // (i+1)-esim table
    }

    tvMesa01->setModel(Modelo[0]);
    tvMesa01->verticalHeader()->hide();
    tvMesa01->setColumnWidth(0, 80);
    tvMesa01->setColumnWidth(1, 80);   // minutes
    tvMesa01->setColumnWidth(2, 48);   // money

    tvMesa02->setModel(Modelo[1]);
    tvMesa02->verticalHeader()->hide();
    tvMesa02->setColumnWidth(0, 80); // min
    tvMesa02->setColumnWidth(1, 80); // min
    tvMesa02->setColumnWidth(2, 48); // sol

    tvMesa03->setModel(Modelo[2]);
    tvMesa03->verticalHeader()->hide();
    tvMesa03->setColumnWidth(0, 80); // min
    tvMesa03->setColumnWidth(1, 80); // min
    tvMesa03->setColumnWidth(2, 48); // sol

    tvMesa04->setModel(Modelo[3]);
    tvMesa04->verticalHeader()->hide();
    tvMesa04->setColumnWidth(0, 80); // min
    tvMesa04->setColumnWidth(1, 80); // min
    tvMesa04->setColumnWidth(2, 48); // sol

    tvMesa05->setModel(Modelo[4]);
    tvMesa05->verticalHeader()->hide();
    tvMesa05->setColumnWidth(0, 80); // min
    tvMesa05->setColumnWidth(1, 80); // min
    tvMesa05->setColumnWidth(2, 48); // sol

    tvMesa06->setModel(Modelo[5]);
    tvMesa06->verticalHeader()->hide();
    tvMesa06->setColumnWidth(0, 80); // min
    tvMesa06->setColumnWidth(1, 80); // min
    tvMesa06->setColumnWidth(2, 48); // sol

    tvMesa07->setModel(Modelo[6]);
    tvMesa07->verticalHeader()->hide();
    tvMesa07->setColumnWidth(0, 80); // min
    tvMesa07->setColumnWidth(1, 80); // min
    tvMesa07->setColumnWidth(2, 48); // sol

    tvMesa08->setModel(Modelo[7]);
    tvMesa08->verticalHeader()->hide();
    tvMesa08->setColumnWidth(0, 80); // min
    tvMesa08->setColumnWidth(1, 80); // min
    tvMesa08->setColumnWidth(2, 48); // sol

    tvMesa09->setModel(Modelo[8]);
    tvMesa09->verticalHeader()->hide();
    tvMesa09->setColumnWidth(0, 80); // min
    tvMesa09->setColumnWidth(1, 80); // min
    tvMesa09->setColumnWidth(2, 48); // sol

    tvMesa10->setModel(Modelo[9]);
    tvMesa10->verticalHeader()->hide();
    tvMesa10->setColumnWidth(0, 80); // min
    tvMesa10->setColumnWidth(1, 80); // min
    tvMesa10->setColumnWidth(2, 48); // sol

    tvMesa11->setModel(Modelo[10]);
    tvMesa11->verticalHeader()->hide();
    tvMesa11->setColumnWidth(0, 80); // min
    tvMesa11->setColumnWidth(1, 80); // min
    tvMesa11->setColumnWidth(2, 48); // sol

    tvMesa12->setModel(Modelo[11]);
    tvMesa12->verticalHeader()->hide();
    tvMesa12->setColumnWidth(0, 80); // min
    tvMesa12->setColumnWidth(1, 80); // min
    tvMesa12->setColumnWidth(2, 48); // sol

    tvMesa13->setModel(Modelo[12]);
    tvMesa13->verticalHeader()->hide();
    tvMesa13->setColumnWidth(0, 80); // min
    tvMesa13->setColumnWidth(1, 80); // min
    tvMesa13->setColumnWidth(2, 48); // sol

    tvMesa14->setModel(Modelo[13]);
    tvMesa14->verticalHeader()->hide();
    tvMesa14->setColumnWidth(0, 80); // min
    tvMesa14->setColumnWidth(1, 80); // min
    tvMesa14->setColumnWidth(2, 48); // sol

    tvMesa15->setModel(Modelo[14]);
    tvMesa15->verticalHeader()->hide();
    tvMesa15->setColumnWidth(0, 80); // min
    tvMesa15->setColumnWidth(1, 80); // min
    tvMesa15->setColumnWidth(2, 48); // sol

    tvMesa16->setModel(Modelo[15]);
    tvMesa16->verticalHeader()->hide();
    tvMesa16->setColumnWidth(0, 80); // min
    tvMesa16->setColumnWidth(1, 80); // min
    tvMesa16->setColumnWidth(2, 48); // sol

    // mesas de pool
    tvMesa17->setModel(Modelo[16]);
    tvMesa17->verticalHeader()->hide();
    tvMesa17->setColumnWidth(0, 80); // min
    tvMesa17->setColumnWidth(1, 80); // min
    tvMesa17->setColumnWidth(2, 48); // sol

    tvMesa18->setModel(Modelo[17]);
    tvMesa18->verticalHeader()->hide();
    tvMesa18->setColumnWidth(0, 80); // min
    tvMesa18->setColumnWidth(1, 80); // min
    tvMesa18->setColumnWidth(2, 48); // sol

    tvMesa19->setModel(Modelo[18]);
    tvMesa19->verticalHeader()->hide();
    tvMesa19->setColumnWidth(0, 80); // min
    tvMesa19->setColumnWidth(1, 80); // min
    tvMesa19->setColumnWidth(2, 48); // sol

    tvMesa20->setModel(Modelo[19]);
    tvMesa20->verticalHeader()->hide();
    tvMesa20->setColumnWidth(0, 80); // min
    tvMesa20->setColumnWidth(1, 80); // min
    tvMesa20->setColumnWidth(2, 48); // sol

    // mesas de billar
    tvMesa21->setModel(Modelo[20]);
    tvMesa21->verticalHeader()->hide();
    tvMesa21->setColumnWidth(0, 80); // min
    tvMesa21->setColumnWidth(1, 80); // min
    tvMesa21->setColumnWidth(2, 48); // sol

    tvMesa22->setModel(Modelo[21]);
    tvMesa22->verticalHeader()->hide();
    tvMesa22->setColumnWidth(0, 80); // min
    tvMesa22->setColumnWidth(1, 80); // min
    tvMesa22->setColumnWidth(2, 48); // sol

    tvMesa23->setModel(Modelo[22]);
    tvMesa23->verticalHeader()->hide();
    tvMesa23->setColumnWidth(0, 80); // min
    tvMesa23->setColumnWidth(1, 80); // min
    tvMesa23->setColumnWidth(2, 48); // sol
}

void Widget::startTimer()
{
    timer->setInterval(1000);           // 1000 mseg = 1 seg
    timer->start();
}

void Widget::playSound()
{
    //    bool retorna;
    QString program = "/usr/bin/play";  /// ubuntu 13.04 :~$ whereis play
    QStringList arguments;
    arguments << "/usr/share/sounds/gnome/default/alerts/glass.ogg";

    soundProcess->start(program, arguments);
    /// function playSound wait for that bin finish the process
    //    if (!myProcess->waitForFinished())
    //        retorna = false;
    //    else
    //        retorna = true;
    qDebug() << "end of playSound function";
    //    return retorna;
}

void Widget::homework()
{
    // query result to write at /tmp folder
    if (!queryWriteReportToFile())  qDebug() << "error # 02 : tmp Report not created";
    if (!printPdfFile())            qDebug() << "error # 03 : pdf Report not created";

}

bool Widget::printPdfFile()
{
    printer->setInputFile(report);
    printer->setOutputFile(dateTimeReport);
    qDebug() << "print start at" << QDateTime::currentDateTime().toString("yyyy:MM:dd:HH:mm:ss");
    emit printFile();
    /// verify if pdf file printed exists
    return true;
}

bool Widget::uploadPdfFile()
{
    ftp->setHost("ftp.industriapadilla.com.pe");
    ftp->setUserName("ftpuser@industriapadilla.com.pe");
    ftp->setPassword("dwnpdll");
    ftp->setPath("/clubsanisidro");
    ftp->setFilename(dateTimeReport + ".pdf");
    emit uploadFile();
    return true;
}

void Widget::checkEnabledTableList()
{
    if (disTables != getListOfTablesByTypeByStatus(isSelectType, Disabled))
    {
        qDebug() << "changed!!!";
        updateTablesListsByType(isSelectType);
        playSound();
    }
}

int Widget::getIdOfTable(QString description)
{
    int idKey = -1;
    idKey = allBillarTables.key(description);
    if (idKey != 0)    return idKey;
    idKey = allPoolTables.key(description);
    if (idKey != 0)    return idKey;
    idKey = allBillasTables.key(description);
    if (idKey != 0)    return idKey;
//    qDebug() << QString("%1").arg(idKey);
    return idKey;
}

Widget::table_t Widget::getTypeOfTable(int tableId)
{
    table_t r = undefined;
    QSqlQuery query;
    query.prepare("select " + fld_typ + " from tables where " + fld_tid + " = :table_id");
    query.bindValue(":table_id", tableId);
    query.exec();
    int fld_typ_no = query.record().indexOf(fld_typ);
    while(query.next())
    {
        r = (table_t)query.value(fld_typ_no).toInt();
    }
//    qDebug() << QString("%1 < %2 < %3").arg(query.size()).arg(fld_typ_no).arg(r);
    return r;
}

QMap<int, Widget::table_s> Widget::queryTablesStatus()
{
    QMap<int, Widget::table_s> retorna;
    QSqlQuery   query;
    QString     diff("diff");

//    select table_id, timestampdiff(minute, (init_time + interval minutes minute), now()) as diff from table_rentals group by table_id desc;

    query.prepare("select " + fld_tid + ", timestampdiff(minute, (init_time + interval minutes minute), now()) as " +
                  diff + " from table_rentals " +
                  "group by " + fld_tid + " desc");
    bool b = query.exec();
    if (!b) return  retorna;
    int dif = 0;
    int fld_tid_no = query.record().indexOf(fld_tid);
    int fld_dif_no = query.record().indexOf(diff);
    while(query.next())
    {
        dif = query.value(fld_dif_no).toInt();
        if (dif < 0)
        {
            retorna.insert(query.value(fld_tid_no).toInt(), Disabled);
        }
        else
        {
            retorna.insert(query.value(fld_tid_no).toInt(), Enabled);
        }
    }
//    qDebug() << "queryTablesStatus():";
//    qDebug() << retorna;
//    QMap((1, 1)(2, 1)(3, 1)(4, 1)(5, 0)(6, 1)(7, 1)(8, 0)(9, 0)(10, 1)(11, 1)(12, 0)(13, 1)(14, 1)(15, 1)(16, 1)(17, 0)(18, 1)(19, 0)(20, 1))
    return retorna;
}

QString Widget::queryRentalsByTable(int tableId)
{
    // existe el id de la tabla ingresada como parámetro?

/*
select init_time, (init_time + interval minutes minute) as fin, money from table_rentals where (table_id = 1 and ((now() - interval 1 day) <= (init_time))) order by init_time Limit 8;
select date_format(init_time, '%H:%i') as Ini, date_format(fin, '%H:%i') as Fin, truncate(money, 1) as `S/.` from(select init_time, (init_time + interval minutes minute) as fin, money from table_rentals where (table_id = 1 and ((now() - interval 1 day) <= (init_time))) order by init_time Limit 8)x;
*/
    QString query;
    query = "select date_format(init_time, '%H:%i') as Ini, date_format(fin, '%H:%i') as Fin, truncate(money, 1) as `S/.` from(select init_time, (init_time + interval minutes minute) as fin, money from table_rentals where (table_id = " +
            QString::number(tableId) +
            " and ((now() - interval 1 day) <= (init_time))) order by init_time Limit " +
            QString::number(visibleRows) +
            ")x";
    return query;
}

void Widget::queryFillTableLists()
{
/*
    2:billas    //1-16
    3:pool      //17-20
    1:billar    //21-23
*/
    if ( !db.isOpen() ) return;
    //
    QSqlQuery   billarQuery("select table_id, description from tables where type = 1");
    while (billarQuery.next())
    {
        allBillarTables.insert(billarQuery.value(0).toInt(), billarQuery.value(1).toString());
    }
    QSqlQuery   billasQuery("select table_id, description from tables where type = 2");
    while (billasQuery.next())
    {
        allBillasTables.insert(billasQuery.value(0).toInt(), billasQuery.value(1).toString());
    }
    QSqlQuery   poolQuery("select table_id, description from tables where type = 3");
    while (poolQuery.next())
    {
        allPoolTables.insert(poolQuery.value(0).toInt(), poolQuery.value(1).toString());
    }
//    qDebug() << "allBillasTables =" << allBillasTables << "\n" << "allPoolTables =" << allPoolTables << "\n" << "allBillarTables =" << allBillarTables;
    /*
QMap((1, "Mesa 1")(2, "Mesa 2")(3, "Mesa 3")(4, "Mesa 4")(5, "Mesa 5")(6, "Mesa 6")(7, "Mesa 7")(8, "Mesa 8")(9, "Mesa 9")(10, "Mesa 10")(11, "Mesa 11")(12, "Mesa 12")(13, "Mesa 13"))
 allPoolTables = QMap((14, "Mesa 14")(15, "Mesa 15")(16, "Mesa 16")(17, "Mesa 17"))
 allBillarTables = QMap((18, "Mesa 18")(19, "Mesa 19")(20, "Mesa 20"))
*/
}

void Widget::getStatusTables()
{
    if ( !db.isOpen() ) return;
    statusTable = queryTablesStatus();
}

QStringList Widget::getListOfTablesByTypeByStatus(int iTableType, table_s status)
{
    getStatusTables();
    if (statusTable.isEmpty())  return QStringList();
    //
    QStringList         listTables;
    QMap<int, QString>  allTables;
    if (iTableType == billar)   allTables   = allBillarTables;
    if (iTableType == billas)   allTables   = allBillasTables;
    if (iTableType == pool)     allTables   = allPoolTables;
    QMapIterator<int, QString>  i(allTables);
    while(i.hasNext())
    {
        i.next();
        QMap<int, table_s>::const_iterator j = statusTable.find(i.key());
        while(j != statusTable.end() && (j.key() == i.key()))
        {
            if (j.value() == status) listTables << i.value();
            ++j;
        }
    }
    return listTables;
}

float Widget::calculateRental(Widget::table_t type, const int minutes)
{
    int minMinutes = 30;    // número mínimo de minutos de cualquier renta
    bool    b = false;
    if (minutes < minMinutes)    b = true;
//    float inc       = 1;        /// S/.1.0
    float fBillas   = 3.0/30;
    float fBillar   = 3.5/30;
    float fPool     = 3.5/30;
//    QTime ini = QTime::fromString("00:00", "HH:mm");
//    QTime fin = QTime::fromString("06:00", "HH:mm");
//    qDebug() << QString("%1 < %2 < %3").arg(ini.toString("HH:mm")).arg(initTime.toString("HH:mm")).arg(fin.toString("HH:mm"));
//    qDebug() << (ini < initTime) << " | " << (initTime < fin);
    float rental = 0;
    if (type == billar) b ? (rental = minMinutes * fBillar) : (rental = minutes * fBillar);
    if (type == billas) b ? (rental = minMinutes * fBillas) : (rental = minutes * fBillas);
    if (type == pool)   b ? (rental = minMinutes * fPool)   : (rental = minutes * fPool);
//    (ini < initTime && initTime < fin) ? (rental += inc) : (rental += 0);
    return rental;
}

bool Widget::queryInsertIntoRentalsTable(int tableId, int interval, float rental)
{
    QSqlQuery query;
    query.prepare("insert into table_rentals (table_id, minutes, money) "
                  "values (:table_id, :minutes, :money)");
    query.bindValue(":table_id", tableId);
    query.bindValue(":minutes", interval);
    query.bindValue(":money", rental);
    return  query.exec();
}

bool Widget::querySelectFreeTables(QMap<QString, QDateTime> &freeTable)
{
    QSqlQuery   query;
//    select table_id from table_rentals where minutes = 1440;
//    int         freeTime = 24*60;   // 24 horas x 60 minutos
//    query.prepare("select " + fld_tid + " from table_rentals where " + fld_min + " = " + freeTime);
    query.prepare("select tables.description, table_rentals.init_time from tables join table_rentals on tables.table_id = table_rentals.table_id where table_rentals.minutes = 1440;");
    bool    retorna     = query.exec();
    int     fld_dsc_no  = query.record().indexOf(fld_dsc);
    int     fld_i_t_no  = query.record().indexOf(fld_i_t);
    while(query.next())
    {
        freeTable.insert(query.value(fld_dsc_no).toString(), query.value(fld_i_t_no).toDateTime());
    }
//    qDebug() << "freeTable =" << freeTable;
    return  retorna;
}

//bool Widget::queryUpdateIntoRentalTable(int tableId, int interval, float rental)
//{
//    // update table_rentals set minutes = 30, money = 3.0 where table_id = 5;
//    QSqlQuery query;
//    query.prepare("update table_rentals set minutes = :minutes, money = :rental where table_id = :table_id");
//    query.bindValue(":table_id", tableId);
//    query.bindValue(":minutes", interval);
//    query.bindValue(":money", rental);
//    return  query.exec();
//}

bool Widget::queryUpdateRowFromRentalsTable(const int rentalId, const int interval, const float rental)
{
    /*
      update table_rentals set minutes = 90, money = 11.5 where table_rental_id = 118;
*/
    qDebug() << "update:" << QString("%1 < %2 < %3").arg(rentalId).arg(interval).arg(rental);
    QSqlQuery query;
    query.prepare("update table_rentals set " + fld_min + " = :minutes, " + fld_mon + " = :money where " + fld_tri + " = :table_rental_id");
    query.bindValue(":table_rental_id", rentalId);
    query.bindValue(":minutes", interval);
    query.bindValue(":money", rental);
    return  query.exec();
}

bool Widget::queryUpdateRowFromRentalsTable(const QString freeTable, const int interval, const float rental)
{
    //    update table_rentals set minutes = 30, money = 3.0 where
    //    (table_id = (select table_id from tables where description = 'Mesa 1') and minutes = 1440);
    QSqlQuery query;
    query.prepare("update table_rentals set minutes = :minutes, money = :money where (table_id = (select table_id from tables where description = :description) and minutes = 1440)");
    query.bindValue(":minutes", interval);
    query.bindValue(":money", rental);
    query.bindValue(":description", freeTable);
    return  query.exec();
}

bool Widget::querySelectLastRowByTableId(const int tableId, int &rentalId, QDateTime &initTime, int &interval)
{
    /*
      select minutes from table_rentals where table_id = 5 order by table_rental_id desc Limit 1;
*/
    QSqlQuery   query;
    query.prepare("select " + fld_tri + ", " + fld_i_t + ", " + fld_min + " from table_rentals where table_id = :table_id order by table_rental_id desc Limit 1;");
    query.bindValue(":table_id", tableId);
    bool b = query.exec();
    int fld_tri_no = query.record().indexOf(fld_tri);
    int fld_i_t_no = query.record().indexOf(fld_i_t);
    int fld_min_no = query.record().indexOf(fld_min);
    while (query.next())
    {
        interval = query.value(fld_min_no).toInt();
        initTime = query.value(fld_i_t_no).toDateTime();
        rentalId = query.value(fld_tri_no).toInt();
    }
//    qDebug() << query.value(fld_min_no) << " | " << query.value(fld_tri_no);
    return b;
}

void Widget::updateTablesListsByType(Widget::table_t type)
{
    enbTables   = getListOfTablesByTypeByStatus(type);
    disTables   = getListOfTablesByTypeByStatus(type, Disabled);
//    qDebug() << "enbTables :" << enbTables;
//    qDebug() << "disTables :" << disTables;
    lstEnbTables->clear();
    lstEnbTables->addItems(enbTables);
    lstDisTables->clear();
    lstDisTables->addItems(disTables);
}

void Widget::updateIntervalCbx()
{
    cbDifTiempo->clear();
    if (bIsEnabledTableSelected)
        cbDifTiempo->addItems(intervals.mid(5));
    else
        cbDifTiempo->addItems(intervals);
}

bool Widget::queryWriteReportToFile()
{
    QSqlQuery   query;
//    query.prepare("select * from table_rentals into outfile '/tmp/report.txt'");    // report.txt does not exist
    /// report file root
    dateTimeReport = QDateTime::currentDateTime().toString("yyyyMMddhhmmss");
    report = "/tmp/reporte" + dateTimeReport + ".csv";
    //    qDebug() << QDateTime::currentDateTime().toString("yyyyMMddhhmmss");
//    select table_id as Mesa, count(table_id) as `número de rentas`, sum(minutes) as `minutos acumulados (min)`, sum(money) as `Ganancia S/.` from table_rentals group by table_id order by `Ganancia S/.` desc into outfile '/tmp/reporte.csv' fields terminated by ',';
    query.prepare("select table_id as Mesa, count(table_id) as `número de rentas`, sum(minutes) as `minutos acumulados (min)`, sum(money) as `Ganancia S/.` from table_rentals group by table_id order by `Ganancia S/.` desc into outfile '" + report + "' fields terminated by ','");    // report.txt does not exist
    return  query.exec();
}

bool Widget::verifyUser(QString user, QString pass)
{
    QString field1 = "username";
    QString field2 = "password";
    QString table = "employees";
//    select password from employees where username = 'atenea';
    QSqlQuery query1;
//    query.prepare("select password from employees where username = 'atenea';");
//    query.prepare("select * from employees;");
    query1.prepare("select " + field2 + " from " + table + " where " + field1 + " = :usuario");
//    select MD5('atenea') = (select password from employees where username = 'atenea');
//    query.prepare("select (select password from employees where username = :usuario) = (select MD5('zeus'))");
//    query.bindValue(":password", pass);
    query1.bindValue(":usuario", user);
    query1.exec();

    QSqlRecord rec1 = query1.record();
//    qDebug() << "Number of columns 1: " << rec1.count();
    int nameCol = rec1.indexOf(field2); // index of the field "name"
    QString pass1 = "";
    while (query1.next())   // waiting for one record
//        qDebug() << query1.value(nameCol).toString(); // output all names
        pass1 = query1.value(nameCol).toString(); // output all names

    QSqlQuery query2;
    query2.prepare("select MD5(:password) as " + field2);
    query2.bindValue(":password", pass);
    query2.exec();

    QSqlRecord rec2 = query2.record();
//    qDebug() << "Number of columns 2: " << rec2.count();
    int nameCol2 = rec2.indexOf(field2); // index of the field "name"
    QString pass2 = "";
    while (query2.next())   // waiting for one record
//        qDebug() << query2.value(nameCol2).toString(); // output all names
        pass2 = query2.value(nameCol2).toString(); // output all names

    return (pass1 == pass2);
}

void Widget::showDigitalWatch()
{
    lcdTime->display(QTime::currentTime().toString("HH:mm:ss"));
//    lcdTime->display(QTime::currentTime().addSecs(-1*60*60).toString("HH:mm:ss"));
}

void Widget::timerHit()
{
    counter++;
//    qDebug() << "counter :" << counter;
    (counter%upperLimit == 0 && counter != 0) ? (bCheck = true, counter = -1) : (bCheck = false);
    if (bCheck)
    {
//        qDebug() << "checkEnabledTablelist()";
//        getStatusTables();
        checkEnabledTableList();
    }
}

void Widget::btSalirSlot()
{
    close();
}

void Widget::btAsignarSlot()
{
//    qDebug() << "type : " << isSelectType;
    if (lstEnbTables->currentItem() == 0)
    {
        QMessageBox::information(this, "ASIGNAR MESA", "Seleccione una mesa", "OK");
        return;
    }
    QString currentTable = lstEnbTables->currentItem()->text();
    qDebug() << "currentTable:" << currentTable;
    int     table_id    = 0;
    float   rental      = 0;
    int     interval    = 60*24;
    if (isSelectType == billar) table_id = allBillarTables.key(currentTable);
    if (isSelectType == billas) table_id = allBillasTables.key(currentTable);
    if (isSelectType == pool)   table_id = allPoolTables.key(currentTable);
    if (cbDifTiempo->currentText() != "LIBRE")  // is a number
    {
        interval = cbDifTiempo->currentText().toInt();
        rental  = calculateRental(isSelectType, interval);
    }
    qDebug() << QString("%1 < %2 < %3").arg(table_id).arg(interval).arg(rental);

    if (queryInsertIntoRentalsTable(table_id, interval, rental))
    {
        setModels();
        updateTablesListsByType(isSelectType);
    }
}

void Widget::btAdicionarSlot()
{
    if (lstDisTables->currentItem() == 0)
    {
        QMessageBox::information(this, "AGREGAR TIEMPO", "Seleccione una mesa rentada", "OK");
        return;
    }
    QString currentTable = lstDisTables->currentItem()->text();
    int     table_id    = 0;
    int     interval_p  = 0;
    if (isSelectType == billar) table_id = allBillarTables.key(currentTable);
    if (isSelectType == billas) table_id = allBillasTables.key(currentTable);
    if (isSelectType == pool)   table_id = allPoolTables.key(currentTable);
    interval_p  = cbDifTiempo->currentText().toInt();
//    qDebug() << "table_id : " << table_id << " | " << "currentTable :" << currentTable << " | " << "interval_p :" << interval_p;
//    calculate again
    int rental_id = 0;
    int interval_o = 0;
    QDateTime   init_time;
    if (!querySelectLastRowByTableId(table_id, rental_id, init_time, interval_o))  qDebug() << "error 01";
//    qDebug() << "rental_id :" << rental_id << " | " << "init_time :" << init_time.time() << " | " << "interval_o :" << interval_o;
    float   rental      = 0;
    int interval_f = interval_o + interval_p;
    rental  = calculateRental(isSelectType, interval_f);  //qDebug() << "rental :" << rental;
    if (queryUpdateRowFromRentalsTable(rental_id, interval_f, rental))
    {
        setModels();
        updateTablesListsByType(isSelectType);
    }
}

void Widget::soundPlayEnd(int code)
{
    if (code == QProcess::NormalExit)
        qDebug() << "ok!!!";
    else
        qDebug() << "bad!!!";
}

void Widget::finishedPrint()
{
    qDebug() << "finished print at" << QDateTime::currentDateTime().toString("yyyy:MM:dd:HH:mm:ss");
    uploadPdfFile();
}

void Widget::finishFileUpload(bool error)
{
    if (!error)
    {
        qDebug() << "complete file upload, no error";
        // some problem with ":"
        QString body = "Reporte correspondiente al " + QDate::currentDate().toString("dd/MM/yyyy") + "\n" + "ftp://ftp.industriapadilla.com.pe/clubsanisidro/" + dateTimeReport + ".pdf\n";
        msg = new QPlainTextEdit();
        msg->setPlainText(body);
        qDebug() << "msg :" << msg->toPlainText();
        smtp->sendMail("ronimarch@gmail.com", "industriapadilla@outlook.com" , "Reporte diario del Club San Isidro", msg->toPlainText());
    }
    else
    {
        qDebug() << "file upload process with error";
    }
}

void Widget::mailSent(QString status)
{
    if(status == "Message sent")
        qDebug() << "mail sent !!!";
}

void Widget::updateFreeTableSlot(QString freeTable, int elapsedTime)
{
    if ((freeTable == "Mesa 0") || (elapsedTime < 0))   return;
    int rental = calculateRental(getTypeOfTable(getIdOfTable(freeTable)),elapsedTime);
    qDebug() << QString("%1 | %2 | %3").arg(freeTable).arg(elapsedTime).arg(rental);
    if (queryUpdateRowFromRentalsTable(freeTable, elapsedTime, rental))
    {
        setModels();
        updateTablesListsByType(isSelectType);
    }
//    if (!b) qDebug() << "Error de actualizacion de mesa libre";
}

void Widget::on_tabWidget_currentChanged(int index)
{
//    qDebug() << "index :" << index;
    if (index == 0) isSelectType = billas;
    if (index == 1) isSelectType = billas;
    if (index == 2) isSelectType = pool;
    if (index == 3) isSelectType = billar;
    updateTablesListsByType(isSelectType);
}

void Widget::keyPressEvent(QKeyEvent *event)
{
    if (event->key() == (Qt::Key_F2))
    {
//        qDebug() << "bye !!!";
//        close();
        TableConf.show();
    }
    if (event->key() == (Qt::Key_F3))
    {
        QMap<QString, QDateTime>    mapFreeTable;
        querySelectFreeTables(mapFreeTable);

        FreeTableDlg    freeTableDlg;
        connect(timer, SIGNAL(timeout()), &freeTableDlg, SLOT(showLcdDisplay()));
        connect(&freeTableDlg, SIGNAL(terminateFreeTable(QString, int)), this, SLOT(updateFreeTableSlot(QString, int)));
        freeTableDlg.setItems(mapFreeTable);
        int r = freeTableDlg.exec();
        qDebug() << "r =" << r;
    }
    QWidget::keyPressEvent(event);
}

void Widget::on_lstDisTables_itemClicked(QListWidgetItem */*item*/)
{
    if (lstEnbTables->currentItem() != 0)   lstEnbTables->reset();
    bIsEnabledTableSelected = false;
    updateIntervalCbx();
}

void Widget::on_lstEnbTables_itemClicked(QListWidgetItem */*item*/)
{
    if (lstDisTables->currentItem() != 0)   lstDisTables->reset();
    bIsEnabledTableSelected = true;
    updateIntervalCbx();
}

void Widget::openDialog()
{
    int r = -1;
    int i = -1;

    QString user = "";
    QString pass = "";

    while(!verifyUser(user, pass))
    {
        LogInDialog d;
        d.setModal(true);
        i++;
        if (i != 0) d.setMessage(QString::fromUtf8("Verifique su usuario y/o contraseña"));

//        qDebug() << d.getUser() << " - " << d.getPassword();
        d.setFocusPassword();
        r = d.exec();
        if (r == QDialog::Rejected)
        {
//            qDebug() << "r :" << r;
            this->close();
            break;
        }
        user = d.getUser();
        pass = d.getPassword();
    }
}
